#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
集成测试运行脚本
自动化运行WebSocket代理桥接服务的完整测试流程
"""

import asyncio
import subprocess
import time
import logging
import argparse
import signal
import sys
import os
from datetime import datetime

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


class TestRunner:
    """测试运行器"""
    
    def __init__(self):
        self.processes = []
        self.running = True
    
    def signal_handler(self, signum, frame):
        """信号处理器"""
        logger.info(f"收到信号 {signum}，正在停止所有进程...")
        self.cleanup()
        sys.exit(0)
    
    def cleanup(self):
        """清理所有启动的进程"""
        logger.info("清理进程...")
        for process in self.processes:
            try:
                if process.poll() is None:  # 进程仍在运行
                    process.terminate()
                    process.wait(timeout=5)
                    logger.info(f"进程 {process.pid} 已终止")
            except subprocess.TimeoutExpired:
                logger.warning(f"进程 {process.pid} 未能正常终止，强制杀死")
                process.kill()
            except Exception as e:
                logger.error(f"清理进程时出错: {str(e)}")
        
        self.processes.clear()
    
    def start_process(self, command: list, name: str, wait_time: int = 2):
        """
        启动进程
        
        Args:
            command: 命令列表
            name: 进程名称
            wait_time: 启动后等待时间
        """
        try:
            logger.info(f"启动 {name}: {' '.join(command)}")
            process = subprocess.Popen(
                command,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True
            )
            self.processes.append(process)
            
            # 等待进程启动
            time.sleep(wait_time)
            
            # 检查进程是否正常启动
            if process.poll() is None:
                logger.info(f"✓ {name} 启动成功 (PID: {process.pid})")
                return process
            else:
                stdout, stderr = process.communicate()
                logger.error(f"✗ {name} 启动失败")
                logger.error(f"stdout: {stdout}")
                logger.error(f"stderr: {stderr}")
                return None
                
        except Exception as e:
            logger.error(f"启动 {name} 时出错: {str(e)}")
            return None
    
    async def run_async_command(self, command: list, name: str, timeout: int = 30):
        """
        运行异步命令
        
        Args:
            command: 命令列表
            name: 命令名称
            timeout: 超时时间
        """
        try:
            logger.info(f"运行 {name}: {' '.join(command)}")
            
            process = await asyncio.create_subprocess_exec(
                *command,
                stdout=asyncio.subprocess.PIPE,
                stderr=asyncio.subprocess.PIPE
            )
            
            try:
                stdout, stderr = await asyncio.wait_for(
                    process.communicate(), 
                    timeout=timeout
                )
                
                if process.returncode == 0:
                    logger.info(f"✓ {name} 执行成功")
                    if stdout:
                        logger.info(f"输出: {stdout.decode()}")
                else:
                    logger.error(f"✗ {name} 执行失败 (返回码: {process.returncode})")
                    if stderr:
                        logger.error(f"错误: {stderr.decode()}")
                
                return process.returncode == 0
                
            except asyncio.TimeoutError:
                logger.error(f"✗ {name} 执行超时")
                process.kill()
                return False
                
        except Exception as e:
            logger.error(f"运行 {name} 时出错: {str(e)}")
            return False
    
    async def test_basic_functionality(self):
        """测试基本功能"""
        logger.info("=" * 60)
        logger.info("开始基本功能测试")
        logger.info("=" * 60)
        
        # 1. 启动WebSocket测试服务器
        server_process = self.start_process(
            ['python', 'test_websocket_server.py', '--host', '127.0.0.1', '--port', '8765'],
            'WebSocket测试服务器',
            wait_time=3
        )
        
        if not server_process:
            logger.error("无法启动WebSocket测试服务器")
            return False
        
        # 2. 启动代理桥接服务
        proxy_process = self.start_process(
            ['python', 'websocket_proxy_bridge.py', '--proxy-port', '8999', '--api-port', '8998'],
            'WebSocket代理桥接服务',
            wait_time=5
        )
        
        if not proxy_process:
            logger.error("无法启动WebSocket代理桥接服务")
            return False
        
        # 3. 等待服务完全启动
        logger.info("等待服务完全启动...")
        await asyncio.sleep(5)
        
        # 4. 测试HTTP API
        api_test_success = await self.run_async_command(
            ['python', 'test_http_api.py', '--api-url', 'http://127.0.0.1:8998', '--test-type', 'health'],
            'HTTP API健康检查测试',
            timeout=10
        )
        
        # 5. 获取连接列表
        connections_test_success = await self.run_async_command(
            ['python', 'test_http_api.py', '--api-url', 'http://127.0.0.1:8998', '--test-type', 'connections'],
            'HTTP API连接列表测试',
            timeout=10
        )
        
        logger.info("=" * 60)
        logger.info("基本功能测试完成")
        logger.info(f"HTTP API健康检查: {'✓ 成功' if api_test_success else '✗ 失败'}")
        logger.info(f"连接列表测试: {'✓ 成功' if connections_test_success else '✗ 失败'}")
        logger.info("=" * 60)
        
        return api_test_success and connections_test_success
    
    async def test_end_to_end_flow(self):
        """测试端到端流程"""
        logger.info("=" * 60)
        logger.info("开始端到端流程测试")
        logger.info("=" * 60)
        
        # 注意：这个测试需要手动配置客户端使用代理
        # 在实际环境中，需要配置WebSocket客户端使用HTTP代理
        logger.info("端到端测试需要手动配置:")
        logger.info("1. 启动WebSocket客户端")
        logger.info("2. 配置客户端使用代理 127.0.0.1:8999")
        logger.info("3. 连接到WebSocket服务器 ws://127.0.0.1:8765")
        logger.info("4. 使用HTTP API发送消息")
        
        # 运行综合API测试
        comprehensive_test_success = await self.run_async_command(
            ['python', 'test_http_api.py', '--api-url', 'http://127.0.0.1:8998', '--test-type', 'comprehensive'],
            '综合API测试',
            timeout=30
        )
        
        logger.info("=" * 60)
        logger.info("端到端流程测试完成")
        logger.info(f"综合API测试: {'✓ 成功' if comprehensive_test_success else '✗ 失败'}")
        logger.info("=" * 60)
        
        return comprehensive_test_success
    
    async def run_performance_test(self, duration: int = 60):
        """
        运行性能测试
        
        Args:
            duration: 测试持续时间（秒）
        """
        logger.info("=" * 60)
        logger.info(f"开始性能测试 (持续 {duration} 秒)")
        logger.info("=" * 60)
        
        # 这里可以添加性能测试逻辑
        # 例如：并发连接测试、消息吞吐量测试等
        
        logger.info("性能测试功能待实现...")
        await asyncio.sleep(2)
        
        logger.info("=" * 60)
        logger.info("性能测试完成")
        logger.info("=" * 60)
        
        return True
    
    async def run_all_tests(self, include_performance: bool = False):
        """运行所有测试"""
        logger.info("开始运行完整测试套件")
        logger.info(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        
        try:
            # 基本功能测试
            basic_success = await self.test_basic_functionality()
            
            if basic_success:
                # 端到端测试
                e2e_success = await self.test_end_to_end_flow()
                
                # 性能测试（可选）
                perf_success = True
                if include_performance:
                    perf_success = await self.run_performance_test()
                
                # 总结
                logger.info("=" * 60)
                logger.info("测试套件执行完成")
                logger.info("=" * 60)
                logger.info(f"基本功能测试: {'✓ 通过' if basic_success else '✗ 失败'}")
                logger.info(f"端到端测试: {'✓ 通过' if e2e_success else '✗ 失败'}")
                if include_performance:
                    logger.info(f"性能测试: {'✓ 通过' if perf_success else '✗ 失败'}")
                
                overall_success = basic_success and e2e_success and perf_success
                logger.info(f"总体结果: {'✓ 所有测试通过' if overall_success else '✗ 部分测试失败'}")
                
                return overall_success
            else:
                logger.error("基本功能测试失败，跳过后续测试")
                return False
                
        except KeyboardInterrupt:
            logger.info("测试被用户中断")
            return False
        except Exception as e:
            logger.error(f"测试执行时出错: {str(e)}")
            return False
        finally:
            self.cleanup()


async def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='WebSocket代理桥接服务集成测试')
    parser.add_argument('--test-type', 
                       choices=['basic', 'e2e', 'performance', 'all'],
                       default='basic',
                       help='测试类型')
    parser.add_argument('--include-performance', action='store_true',
                       help='包含性能测试（仅在all模式下有效）')
    parser.add_argument('--duration', type=int, default=60,
                       help='性能测试持续时间（秒）')
    
    args = parser.parse_args()
    
    # 创建测试运行器
    runner = TestRunner()
    
    # 注册信号处理器
    signal.signal(signal.SIGINT, runner.signal_handler)
    signal.signal(signal.SIGTERM, runner.signal_handler)
    
    try:
        if args.test_type == 'basic':
            success = await runner.test_basic_functionality()
        elif args.test_type == 'e2e':
            success = await runner.test_end_to_end_flow()
        elif args.test_type == 'performance':
            success = await runner.run_performance_test(args.duration)
        else:  # all
            success = await runner.run_all_tests(args.include_performance)
        
        exit_code = 0 if success else 1
        logger.info(f"测试完成，退出码: {exit_code}")
        sys.exit(exit_code)
        
    except Exception as e:
        logger.error(f"测试运行器异常: {str(e)}")
        runner.cleanup()
        sys.exit(1)


if __name__ == "__main__":
    asyncio.run(main())